package com.joysuch.wwyt.edu.schedule;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.joysuch.wwyt.bp.bean.BpBaseUserBean;
import com.joysuch.wwyt.bp.constant.AppNotifyContentPre;
import com.joysuch.wwyt.bp.entity.BpCommonNotifyRel;
import com.joysuch.wwyt.bp.enums.CommonNotifyRelType;
import com.joysuch.wwyt.bp.service.BpCommonNotifyRelService;
import com.joysuch.wwyt.common.entity.CommonBusinessNotice;
import com.joysuch.wwyt.common.entity.CommonIndexNotify;
import com.joysuch.wwyt.common.enums.AppBusinessNoticeTypes;
import com.joysuch.wwyt.common.enums.CommonIndexNotifyTypes;
import com.joysuch.wwyt.common.repository.CommonIndexNotifyDao;
import com.joysuch.wwyt.common.service.CommonBusinessNoticeService;
import com.joysuch.wwyt.common.service.CommonIndexNotifyService;
import com.joysuch.wwyt.core.common.util.DateTimeUtil;
import com.joysuch.wwyt.core.common.util.JsonUtil;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.repository.BaseConfigDao;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.edu.entity.EduTrainningPlan;
import com.joysuch.wwyt.edu.repository.EduTrainningPlanDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Component
public class EduTrainingPlanNotifySchedule {

    @Autowired
    private EduTrainningPlanDao planDao;
    @Autowired
    private BaseConfigDao baseConfigDao;
    @Autowired
    private BpCommonNotifyRelService commonNotifyRelService;


    @Autowired
    private CommonIndexNotifyDao commonIndexNotifyDao;
    @Autowired
    private CommonIndexNotifyService commonIndexNotifyService;
    @Autowired
    private CommonBusinessNoticeService commonBusinessNoticeService;
    @Autowired
    private BaseUserDao baseUserDao;

    // @Scheduled(cron = "0 10 0 * * ?")
    // @Scheduled(fixedDelay = 60000, initialDelay = 10 * 1000)
    public void run() {

        try {
            doTask();
            log.info("do edu plan notice success");
        } catch (Exception e) {
            log.error("do edu plan notice error", e);
        }


    }

    private void doTask() {
        BaseConfig config = baseConfigDao.findFirstByCodeNative("edu.trainning.plan.notice.day");
        if (config == null || StringUtils.isEmpty(config.getValue())) {
            log.info("not found yingji.xiaofang.notice.day config");
            return;
        }
        int days = Integer.parseInt(config.getValue().trim());
        // 今日零点
        final DateTime todayBegin = DateUtil.beginOfDay(new Date());
        // 开始时间 今日零点往前推 days天
        DateTime startDate = DateUtil.offsetDay(todayBegin, days);
        // 结束时间 今日零点往前推 days+1天
        DateTime endDate = DateUtil.offsetDay(startDate, 1);
        List<EduTrainningPlan> planList = planDao.findByDate(startDate, endDate);
        if (CollectionUtil.isEmpty(planList)) {
            return;
        }
        Set<Long> planIds = planList.stream().map(EduTrainningPlan::getId).collect(Collectors.toSet());

        Map<Long, Integer> countMap = commonNotifyRelService.countMapByRelAndType(planIds, CommonNotifyRelType.edu_training_plan);
        // count数大于零的，不处理
        planList = planList.stream().filter(p -> {
            Integer count = countMap.get(p.getId());
            return Objects.isNull(count) || count <= 0;
        }).collect(Collectors.toList());

        if (CollectionUtil.isEmpty(planList)) {
            return;
        }
        // 计划相关的人员
        Map<Long, List<BpBaseUserBean>> planUserMap = buildPlanUserMap(planList);
        List<BpCommonNotifyRel> commonNotifyRels = new ArrayList<>();
        List<CommonIndexNotify> notifyList = Lists.newArrayList();
        List<CommonBusinessNotice> commonBusinessNotices = Lists.newArrayList();

        Date now = new Date();
        for (EduTrainningPlan plan : planList) {
            notice(plan, days, notifyList, commonBusinessNotices, planUserMap);
            BpCommonNotifyRel bpCommonNotifyRel = new BpCommonNotifyRel();
            bpCommonNotifyRel.setRelId(plan.getId());
            bpCommonNotifyRel.setType(CommonNotifyRelType.edu_training_plan.getCode());
            bpCommonNotifyRel.setOrgCode("001-001");
            bpCommonNotifyRel.setTenentId(1L);
            bpCommonNotifyRel.setCreateBy(9784L);
            bpCommonNotifyRel.setUpdateBy(9784L);

            bpCommonNotifyRel.setCreateTime(now);
            bpCommonNotifyRel.setUpdateTime(now);
            bpCommonNotifyRel.setDeleteFlag("0");
            commonNotifyRels.add(bpCommonNotifyRel);
        }
        if (CollectionUtil.isNotEmpty(commonNotifyRels)) {
            commonNotifyRelService.saveBatch(commonNotifyRels);
        }
        if (CollectionUtil.isNotEmpty(notifyList)) {
            commonIndexNotifyDao.saveAll(notifyList);
        }
        if (CollectionUtil.isNotEmpty(commonBusinessNotices)) {
            commonBusinessNoticeService.saveBatch(commonBusinessNotices);
        }
    }

    private void notice(EduTrainningPlan plan, int days, List<CommonIndexNotify> notifyList,
                        List<CommonBusinessNotice> commonBusinessNotices, Map<Long, List<BpBaseUserBean>> planUserMap) {
        List<BpBaseUserBean> useDeparemergencyMembersts = planUserMap.get(plan.getId());

        Date now = new Date();
        for (BpBaseUserBean baseUser : useDeparemergencyMembersts) {
            //提醒逻辑更改为证书提醒时间加上提前量后的提醒时间在当前时间之前的需要发送提醒消息,
            //为了防止重复生成提醒消息,以cert_user_id,和提醒时间以及提醒人员id,以及证书管理的类型(到期，复证),以及证书的过期日期为条件去查重,符合条件的不去生成通知
            CommonIndexNotify notify = new CommonIndexNotify();
            //因为是定时任务生成的通知，兼容提前量大于剩余时间的数据，提醒时间统一取当前时间
//            notify.setBusinessDate();
            //到期提醒日期
            notify.setRemindDate(LocalDate.now());
            //到期提醒时间
            notify.setRemindDateTime(LocalDateTime.now());


            notify.setType(CommonIndexNotifyTypes.EDU_TRAINING_PLAN.getType());
            notify.setReadFlag(0);
            notify.setQueueOrNot(0);
            notify.setRemindedOrNot(0);
            //到期提醒日期
            notify.setRemindDate(LocalDate.now());
            //到期提醒时间
            notify.setRemindDateTime(LocalDateTime.now());
            //人员id
            notify.setUserId(baseUser.getId());
            //提醒message格式：人+证书+日期+即将过期
            String message = baseUser.getName() + " 您的培训计划:" + plan.getName()
                    + "(" + plan.getCode() + ")还有" + days + "天即将开始";


            notify.setTenentId(plan.getTenentId());
            notify.setOrgCode(plan.getOrgCode());
            notify.setCreateBy(null);
            notify.setUpdateBy(null);
            notify.setReadFlag(0);
            notify.setQueueOrNot(1);
            notify.setRemindedOrNot(1);
            notify.setEduCertUserId(baseUser.getId());
//            notify.setRecordId(baseUser.getId());
            notify.setNotifyMessage(message);

            notifyList.add(notify);

            CommonBusinessNotice notice = new CommonBusinessNotice();
            notice.setNoticeTitle(AppNotifyContentPre.TASK_NOTIFY);
            notice.setBusinessType(AppBusinessNoticeTypes.EDU.getType());
            notice.setNoticeContent(message);
            notice.setNoticeUser(baseUser.getId());
            notice.setReaded("0");
            notice.setRefId(plan.getId());
            notice.setSendTime(new Date());

            notice.setTenentId(1L);
            notice.setCreateBy(9784L);
            notice.setUpdateBy(9784L);

            notice.setCreateTime(now);
            notice.setUpdateTime(now);
            notice.setDeleteFlag("0");

            commonBusinessNotices.add(notice);
        }
    }

    private Map<Long, List<BpBaseUserBean>> buildPlanUserMap(List<EduTrainningPlan> plans) {
        // 所有相关部门
        Set<Long> deptIds = new HashSet<>();
        plans.forEach(e -> {
            deptIds.addAll(JsonUtil.fromListJson(e.getDepartIds(), Long.class));
        });
        // 所有相关用户
        List<BaseUser> baseUsers = baseUserDao.findIdByDepartIdInV2(new ArrayList<>(deptIds));
        Map<Long, List<BaseUser>> userDeptGroup = baseUsers.stream().collect(Collectors.groupingBy(BaseUser::getDepartId));
        HashMap<Long, List<BpBaseUserBean>> result = new HashMap<>();
        for (EduTrainningPlan plan : plans) {
            // 当前计划相关部门
            List<Long> currentDeptIds = JsonUtil.fromListJson(plan.getDepartIds(), Long.class);
            if (CollectionUtil.isEmpty(currentDeptIds)) {
                continue;
            }
            // 每个部门的人员
            List<BpBaseUserBean> userBeanList = new ArrayList<>();
            for (Long deptId : currentDeptIds) {
                List<BaseUser> users = userDeptGroup.get(deptId);
                users.forEach(baseUser -> {
                    BpBaseUserBean bean = new BpBaseUserBean();
                    bean.setId(baseUser.getId());
                    bean.setName(baseUser.getRealName());
                    userBeanList.add(bean);
                });
            }
            result.put(plan.getId(), userBeanList);

        }
        return result;
    }
}
